<template>
  <!-- 地图画布容器 -->
  <div ref="mapContainer" class="map-wrapper">
    <canvas ref="canvas" class="map-canvas" @dblclick.stop="handleDoubleClick"></canvas>
    <!-- 1:1俯视图按钮 -->
    <button class="top-view-btn" :disabled="isTopViewLoading" @click="handleTopViewClick">
      1 : 1
    </button>
    <!-- 窗口大小监听 -->
    <q-resize-observer @resize="handleWindowResize"></q-resize-observer>
  </div>
</template>

<script setup>
// 1. 导入依赖
import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
import * as THREE from 'three'
import { MapControls } from 'three/addons/controls/MapControls.js'
import { MapUtils, initLights } from './MapGlobal/MapUtils'
import { CameraUtils } from './MapGlobal/CameraUtils'
import { handleMap3dData } from './MapGlobal/utils'

const props = defineProps({
  loading: Boolean, openedMap: Object, mapJSON: String,
  refreshMap: Boolean
})
const emits = defineEmits(['update:loading', 'update:refreshMap'])

// 2. 数据解析



// 3. 组件状态与引用
const canvas = ref(null)
const mapContainer = ref(null)  // 新增：地图容器引用
const screenSize = ref({ width: 0, height: 0 })
const isTopViewLoading = ref(false)

// 4. Three.js核心对象
let scene = null
let camera = null
let renderer = null
let controls = null
let mapDrawer = null
let cameraController = null // 相机控制工具（聚合所有相机相关操作）

// 5. 配置参数（仅保留组件级配置）
const animationConfig = {
  duration: 1.6, // 统一动画时长
  globalViewPadding: 0.5
}

// 6. 获取当前容器的实际尺寸
const getContainerSize = () => {
  if (!mapContainer.value) return { width: 1700, height: 851 } // 降级默认值

  // 获取容器的计算样式
  const computedStyle = window.getComputedStyle(mapContainer.value)

  // 解析宽度和高度（处理可能的px、%等单位）
  const width = parseInt(computedStyle.width, 10) || 1700
  const height = parseInt(computedStyle.height, 10) || 851

  // 确保最小尺寸，避免过小导致异常
  return {
    width: Math.max(width, 800),  // 最小宽度800px
    height: Math.max(height, 400) // 最小高度400px
  }
}

// 6. 初始化Three.js核心逻辑
const initThreeJS = (mapInfo) => {
  if (!mapInfo) return
  // 先确保容器已渲染
  if (!mapContainer.value) {
    setTimeout(initThreeJS, 100)
    return
  }

  // 创建场景
  scene = new THREE.Scene()

  // 初始化渲染器
  renderer = new THREE.WebGLRenderer({
    canvas: canvas.value,
    antialias: true,
    alpha: true
  })

  // 获取并设置动态尺寸
  const containerSize = getContainerSize()
  screenSize.value = containerSize

  renderer.setSize(containerSize.width, containerSize.height)
  renderer.setPixelRatio(window.devicePixelRatio)
  renderer.setAnimationLoop(animate)

  // 初始化相机
  camera = new THREE.PerspectiveCamera(
    60, // 初始视野角
    containerSize.width / containerSize.height,
    0.1,
    1000
  )

  // 初始化控制器
  controls = new MapControls(camera, renderer.domElement)
  controls.enableDamping = true
  controls.dampingFactor = 0.05
  controls.screenSpacePanning = false
  controls.maxPolarAngle = Math.PI / 2
  controls.zoomToCursor = true
  controls.enableDoubleClickZoom = false

  // 初始化灯光
  initLights(scene)

  // 初始化工具类（将所有相机操作委托给CameraUtils）
  mapDrawer = new MapUtils(scene, camera, renderer)
  // 传入必要参数和配置，聚合相机控制逻辑
  cameraController = new CameraUtils(camera, controls, scene, {
    tiltAngle: Math.PI / 7,        // 聚焦倾斜角度
    distanceFactor: 4.0,           // 聚焦拉远因子
    heightOffset: 1.5,             // 聚焦高度偏移
    animationDuration: animationConfig.duration,
    topView: {
      polarAngle: 0.02,
      heightRatio: 1.2
    }
  })

  // 绘制地图并适配初始视图
  mapDrawer.drawMap(mapInfo)
  console.log(mapInfo, 'mapInfo')
  cameraController.fitMapToViewMaximize(mapInfo, 0.05)
  emits('update:loading', false)
  emits('update:refreshMap', false)

  // 使用动态获取的尺寸初始化
  handleWindowResize(containerSize)
}

watch(() => props.mapJSON, val => {
  if (!val) return
  const mapInfo = handleMap3dData(JSON.parse(val))
  initThreeJS(mapInfo)
}, { immediate: true, deep: true })


// 7. 动画循环
const animate = () => {
  controls.update()
  renderer.render(scene, camera)
}

// 8. 窗口resize处理
const handleWindowResize = (size) => {
  screenSize.value = size
  if (!camera || !renderer) return
  cameraController.handleResize(size)
  renderer.setSize(size.width, size.height)
}

// 9. 双击事件处理（委托给cameraController）
const handleDoubleClick = (e) => {
  cameraController.handleDoubleClick(e, renderer)
}

// 10. 俯视图按钮点击处理
const handleTopViewClick = () => {
  isTopViewLoading.value = true
  cameraController.animateToTopView()
  // 匹配动画时长恢复按钮状态
  setTimeout(() => {
    isTopViewLoading.value = false
  }, animationConfig.duration * 1000)
}

// 11. 组件生命周期
onMounted(() => {
  // 确保DOM渲染完成后再初始化
  nextTick(() => {
    initThreeJS()
  })
})

onUnmounted(() => {
  if (renderer) renderer.setAnimationLoop(null)
  if (mapDrawer) mapDrawer.clearMap()
})
</script>

<style scoped>
/* 样式保持不变，但确保容器占满可用空间 */
.map-wrapper {
  position: relative;
  width: 100%;
  height: 100%;
  min-width: 800px;
  /* 确保最小宽度 */
  min-height: 400px;
  /* 确保最小高度 */
}

.map-canvas {
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.top-view-btn {
  position: absolute;
  bottom: 20px;
  right: 20px;
  padding: 8px 16px;
  background-color: #66b1ff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  z-index: 100;
  transition: background-color 0.2s;
}

.top-view-btn:disabled {
  background-color: #c0ccda;
  cursor: not-allowed;
}

.top-view-btn:hover:not(:disabled) {
  background-color: #409eff;
}
</style>